/*******************************************************************************
 * Copyright (c) 2009 Kevin Bierhoff and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Kevin Bierhoff - initial API and implementation
 *******************************************************************************/
package com.googlecode.twelfdevtools.editor;

import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextDoubleClickStrategy;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlinkPresenter;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.quickassist.IQuickAssistAssistant;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.source.DefaultAnnotationHover;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;



public class TwelfEditorConfiguration extends SourceViewerConfiguration {
	private XMLDoubleClickStrategy doubleClickStrategy;
//	private XMLTagScanner tagScanner;
	private TwelfScanner scanner;
	private final ColorManager colorManager;
	private IAnnotationHover annotationHover;
	private ITextHover textHover;
	private final TwelfEditor editor;

	public TwelfEditorConfiguration(TwelfEditor editor, ColorManager colorManager) {
		this.editor = editor;
		this.colorManager = colorManager;
	}
//	public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
//		return new String[] {
//			IDocument.DEFAULT_CONTENT_TYPE,
//			XMLPartitionScanner.XML_COMMENT,
//			XMLPartitionScanner.XML_TAG };
//	}
	@Override
	public ITextDoubleClickStrategy getDoubleClickStrategy(
		ISourceViewer sourceViewer,
		String contentType) {
		if (doubleClickStrategy == null)
			doubleClickStrategy = new XMLDoubleClickStrategy();
		return doubleClickStrategy;
	}

	protected TwelfScanner getTwelfScanner() {
		if (scanner == null) {
			scanner = new TwelfScanner(colorManager);
			scanner.setDefaultReturnToken(
				new Token(
					new TextAttribute(
						colorManager.getColor(ITwelfColorConstants.DEFAULT))));
		}
		return scanner;
	}
	
//	protected XMLTagScanner getXMLTagScanner() {
//		if (tagScanner == null) {
//			tagScanner = new XMLTagScanner(colorManager);
//			tagScanner.setDefaultReturnToken(
//				new Token(
//					new TextAttribute(
//						colorManager.getColor(IXMLColorConstants.TAG))));
//		}
//		return tagScanner;
//	}

	@Override
	public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
		PresentationReconciler reconciler = new PresentationReconciler();

//		DefaultDamagerRepairer dr =
//			new DefaultDamagerRepairer(getXMLTagScanner());
//		reconciler.setDamager(dr, XMLPartitionScanner.XML_TAG);
//		reconciler.setRepairer(dr, XMLPartitionScanner.XML_TAG);
//
		DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getTwelfScanner());
		reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
		reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);

//		NonRuleBasedDamagerRepairer ndr =
//			new NonRuleBasedDamagerRepairer(
//				new TextAttribute(
//					colorManager.getColor(IXMLColorConstants.XML_COMMENT)));
//		reconciler.setDamager(ndr, XMLPartitionScanner.XML_COMMENT);
//		reconciler.setRepairer(ndr, XMLPartitionScanner.XML_COMMENT);
//
		return reconciler;
	}
	
	@Override
	public ITextHover getTextHover(ISourceViewer sourceViewer,
			String contentType, int stateMask) {
		if(textHover == null) {
			textHover = new TwelfTypeHover(editor, sourceViewer);
		}
		return textHover;
	}
	
	@Override
	public ITextHover getTextHover(ISourceViewer sourceViewer,
			String contentType) {
		if(textHover == null) {
			textHover = new TwelfTypeHover(editor, sourceViewer);
		}
		return textHover;
	}
	
	@Override
	public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
		if(annotationHover == null) {
			// display error messages when hovering over problem markers
			annotationHover = new TwelfAnnotationHover();
		}
		return annotationHover;
	}
	
	@Override
	public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
		if(sourceViewer == null)
			return null;
		TwelfHyperlinkDetector result = new TwelfHyperlinkDetector();
		// set editor as context so we can look up adapters
		result.setContext(editor);
		return new IHyperlinkDetector[] { result };
	}

	@Override
	public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
		ContentAssistant autoComplete = new ContentAssistant();
		autoComplete.setContentAssistProcessor(new TwelfContentAssist(editor),
				IDocument.DEFAULT_CONTENT_TYPE);
		return autoComplete;
	}

	@Override
	public IQuickAssistAssistant getQuickAssistAssistant(ISourceViewer sourceViewer) {
		return null;
	}

	/**
	 * Annotation hovers are
	 * hovers on the column left of an editor text field.
	 * Used to filter Twelf typing information, but hovering
	 * next to a constant will just show the constant now.
	 * @author Kevin Bierhoff
	 */
	private class TwelfAnnotationHover extends DefaultAnnotationHover 
	implements IAnnotationHover {

//		@Override
//		protected boolean isIncluded(Annotation annotation) {
//			if(annotation instanceof MarkerAnnotation) {
//				MarkerAnnotation ma = (MarkerAnnotation) annotation;
//				IMarker m = ma.getMarker();
//				try {
//					return m.isSubtypeOf(IMarker.PROBLEM) 
//						|| m.isSubtypeOf(IMarker.BOOKMARK)
//						|| m.isSubtypeOf(IMarker.TASK);
//				}
//				catch(CoreException e) {
//					// TODO logging
//					e.printStackTrace();
//					return false;
//				}
//			}
//			else
//				return false;
//		}
		
	}

}